/********************************************************************************
 * Project Name		[JavaEE_Components]
 * File Name     	[AccountServlet.java]
 * Creation Date 	[2015-01-01]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ********************************************************************************/
package javamail.cases.servlet;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import javamail.cases.Constants;
import javamail.cases.bean.User;
import javamail.cases.dao.UserDao;
import javamail.cases.utils.LinkUtils;
import javamail.cases.utils.MailUtils;

/**
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 * 
 */
@WebServlet(value = "/account.do")
public class AccountServlet extends HttpServlet {

	private static final long serialVersionUID = -6403029293774006777L;

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doPost(request, response);
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String methodName = request.getParameter("method");
		try {
			Method method = AccountServlet.class.getDeclaredMethod(methodName, HttpServletRequest.class,
					HttpServletResponse.class);
			method.invoke(this, request, response);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 注册新用户的Servlet
	 * 
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void register(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String userName = request.getParameter("username");
		String password = request.getParameter("password");
		String password2 = request.getParameter("password2");
		String email = request.getParameter("email");

		UserDao userDao = UserDao.getInstance();

		Map<String, String> errors = new LinkedHashMap<String, String>();
		if (userName == null || "".equals(userName)) {
			errors.put("username", "用户名不能为空!");
		} else if (userName != null && userDao.findUserByName(userName) != null) {
			errors.put("username", "该用户已注册!");
		}

		if (password == null || "".equals(password)) {
			errors.put("password", "密码不能为空!");
		} else if (password != null && password.length() < 3) {
			errors.put("password", "密码长度不能低于3位!");
		}

		if (password2 == null || "".equals(password2)) {
			errors.put("password2", "确认密码不能为空!");
		} else if (password2 != null && !password2.equals(password)) {
			errors.put("password2", "两次输入的密码不一致!");
		}

		if (email == null || "".equals(email)) {
			errors.put("email", "email不能为空!");

		} else if (email != null
				&& !email.matches("[0-9a-zA-Z_-]+@[0-9a-zA-Z_-]+\\.[0-9a-zA-Z_-]+(\\.[0-9a-zA-Z_-])*")) {
			errors.put("email", "email格式不正确!");
		}

		System.out.println("in register class");
		System.out.println(errors);

		if (!errors.isEmpty()) {
			request.setAttribute("errors", errors);
			request.getRequestDispatcher("/jsp/register.jsp").forward(request, response);
			return;
		}

		User user = new User();
		user.setUsername(userName);
		user.setPassword(password);
		user.setEmail(email);
		user.setActivated(false);

		userDao.addUser(user);

		// 注册成功后,发送帐户激活链接
		MailUtils.sendAccountActivateMail(user);

		// 注册成功直接将当前用户保存到session中
		request.getSession().setAttribute("user", user);
		request.getRequestDispatcher("/jsp/registerSuccess.jsp").forward(request, response);
	}

	/**
	 * 激活帐户的方法
	 * 
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void activateAccount(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 该请求的连接格式为http://localhost:8080/JavaEE_Components/activateAccount?id=12345&activateCode=xxxxx
		String idValue = request.getParameter("id");
		int id = -1;
		try {
			id = Integer.parseInt(idValue);
		} catch (NumberFormatException e) {
			throw new ServletException("无效的用户", e);
		}

		UserDao userDao = UserDao.getInstance();
		User user = userDao.findUserById(id);
		user.setRandomCode(request.getParameter(Constants.ACTIVATE_CODE));
		user.setActivated(LinkUtils.validateRandomCode(user, user.getRandomCode()));
		userDao.updateUser(user);

		request.getSession().setAttribute("user", user);

		request.getRequestDispatcher("/jsp/accountActivate.jsp").forward(request, response);
	}

	/**
	 * 用户登陆方法[未实现]
	 * 
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void login(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO unimplemented
	}

	/**
	 * 从"忘记密码"链接跳转到"重置密码"页面
	 * 
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void reset(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.getRequestDispatcher("/jsp/forgotPassword").forward(request, response);
	}

	/**
	 * 重置密码
	 * 
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void resetPassword(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String userNameOrEmail = request.getParameter("userNameOrEmail");
		UserDao userDao = UserDao.getInstance();
		User user = userDao.findUserByNameOrEmail(userNameOrEmail);
		if (user == null) {
			request.setAttribute("errorMsg", userNameOrEmail + ", 不存在!");
			request.getRequestDispatcher("/jsp/forgotPassword.jsp").forward(request, response);
			return;
		}

		user.setActivated(false);
		userDao.updateUser(user);

		// 发送重新设置密码的链接
		MailUtils.sendAccountResetMail(user);
		request.setAttribute("sendMailMsg", "您的申请已提交成功, 请查看您的" + user.getEmail() + "邮箱.");
		request.getRequestDispatcher("/jsp/submitSuccess.jsp").forward(request, response);
	}

	/**
	 * 从邮件跳转到重置密码页面
	 * 
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void goToResetPage(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String id = request.getParameter("id");
		UserDao userDao = UserDao.getInstance();
		User user = userDao.findUserById(Integer.parseInt(id));
		user.setRandomCode(request.getParameter(Constants.RESET_CODE));
		user.setActivated(LinkUtils.validateRandomCode(user, user.getRandomCode()));
		userDao.updateUser(user);

		request.getSession().setAttribute("user", user);
		request.getRequestDispatcher("/jsp/resetPassword.jsp").forward(request, response);
	}
}
